{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:01:16.269658100Z",
     "start_time": "2025-06-07T03:01:16.259486200Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import os\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler        # 特征处理\n",
    "import xgboost as xgb\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "from sklearn.metrics import accuracy_score, roc_auc_score\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.metrics import classification_report\n",
    "from sklearn.preprocessing import LabelEncoder\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "\n",
    "os.chdir(r'E:\\temp_dir\\workspace\\eee\\company_talent_loss\\wanghongge')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1100 entries, 0 to 1099\n",
      "Data columns (total 31 columns):\n",
      " #   Column                    Non-Null Count  Dtype \n",
      "---  ------                    --------------  ----- \n",
      " 0   Attrition                 1100 non-null   int64 \n",
      " 1   Age                       1100 non-null   int64 \n",
      " 2   BusinessTravel            1100 non-null   object\n",
      " 3   Department                1100 non-null   object\n",
      " 4   DistanceFromHome          1100 non-null   int64 \n",
      " 5   Education                 1100 non-null   int64 \n",
      " 6   EducationField            1100 non-null   object\n",
      " 7   EmployeeNumber            1100 non-null   int64 \n",
      " 8   EnvironmentSatisfaction   1100 non-null   int64 \n",
      " 9   Gender                    1100 non-null   object\n",
      " 10  JobInvolvement            1100 non-null   int64 \n",
      " 11  JobLevel                  1100 non-null   int64 \n",
      " 12  JobRole                   1100 non-null   object\n",
      " 13  JobSatisfaction           1100 non-null   int64 \n",
      " 14  MaritalStatus             1100 non-null   object\n",
      " 15  MonthlyIncome             1100 non-null   int64 \n",
      " 16  NumCompaniesWorked        1100 non-null   int64 \n",
      " 17  Over18                    1100 non-null   object\n",
      " 18  OverTime                  1100 non-null   object\n",
      " 19  PercentSalaryHike         1100 non-null   int64 \n",
      " 20  PerformanceRating         1100 non-null   int64 \n",
      " 21  RelationshipSatisfaction  1100 non-null   int64 \n",
      " 22  StandardHours             1100 non-null   int64 \n",
      " 23  StockOptionLevel          1100 non-null   int64 \n",
      " 24  TotalWorkingYears         1100 non-null   int64 \n",
      " 25  TrainingTimesLastYear     1100 non-null   int64 \n",
      " 26  WorkLifeBalance           1100 non-null   int64 \n",
      " 27  YearsAtCompany            1100 non-null   int64 \n",
      " 28  YearsInCurrentRole        1100 non-null   int64 \n",
      " 29  YearsSinceLastPromotion   1100 non-null   int64 \n",
      " 30  YearsWithCurrManager      1100 non-null   int64 \n",
      "dtypes: int64(23), object(8)\n",
      "memory usage: 266.5+ KB\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "data_source = pd.read_csv('./data/train.csv')\n",
    "# print(data_source.head(10))\n",
    "print(data_source.info())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:01:19.732008900Z",
     "start_time": "2025-06-07T03:01:19.712586800Z"
    }
   },
   "id": "4495404d3a5fc401"
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1100 entries, 0 to 1099\n",
      "Data columns (total 23 columns):\n",
      " #   Column                    Non-Null Count  Dtype \n",
      "---  ------                    --------------  ----- \n",
      " 0   Age                       1100 non-null   int64 \n",
      " 1   Department                1100 non-null   object\n",
      " 2   DistanceFromHome          1100 non-null   int64 \n",
      " 3   Education                 1100 non-null   int64 \n",
      " 4   EnvironmentSatisfaction   1100 non-null   int64 \n",
      " 5   Gender                    1100 non-null   object\n",
      " 6   JobLevel                  1100 non-null   int64 \n",
      " 7   JobSatisfaction           1100 non-null   int64 \n",
      " 8   MaritalStatus             1100 non-null   object\n",
      " 9   MonthlyIncome             1100 non-null   int64 \n",
      " 10  NumCompaniesWorked        1100 non-null   int64 \n",
      " 11  OverTime                  1100 non-null   object\n",
      " 12  PercentSalaryHike         1100 non-null   int64 \n",
      " 13  PerformanceRating         1100 non-null   int64 \n",
      " 14  RelationshipSatisfaction  1100 non-null   int64 \n",
      " 15  StockOptionLevel          1100 non-null   int64 \n",
      " 16  TotalWorkingYears         1100 non-null   int64 \n",
      " 17  WorkLifeBalance           1100 non-null   int64 \n",
      " 18  YearsAtCompany            1100 non-null   int64 \n",
      " 19  YearsInCurrentRole        1100 non-null   int64 \n",
      " 20  YearsSinceLastPromotion   1100 non-null   int64 \n",
      " 21  YearsWithCurrManager      1100 non-null   int64 \n",
      " 22  Attrition                 1100 non-null   int64 \n",
      "dtypes: int64(19), object(4)\n",
      "memory usage: 197.8+ KB\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "df = data_source[\n",
    "    ['Age', 'Department', 'DistanceFromHome', 'Education', 'EnvironmentSatisfaction', 'Gender', 'JobLevel', 'JobSatisfaction', 'MaritalStatus', 'MonthlyIncome', 'NumCompaniesWorked', 'OverTime', 'PercentSalaryHike', 'PerformanceRating', 'RelationshipSatisfaction', 'StockOptionLevel', 'TotalWorkingYears', 'WorkLifeBalance', 'YearsAtCompany', 'YearsInCurrentRole', 'YearsSinceLastPromotion', 'YearsWithCurrManager','Attrition']]\n",
    "# print(type(df))\n",
    "print(df.info())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:01:25.870493400Z",
     "start_time": "2025-06-07T03:01:25.860545100Z"
    }
   },
   "id": "fe2870f0bbe8648a"
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1100 entries, 0 to 1099\n",
      "Data columns (total 25 columns):\n",
      " #   Column                    Non-Null Count  Dtype\n",
      "---  ------                    --------------  -----\n",
      " 0   Age                       1100 non-null   int64\n",
      " 1   Department                1100 non-null   int64\n",
      " 2   DistanceFromHome          1100 non-null   int64\n",
      " 3   Education                 1100 non-null   int64\n",
      " 4   EnvironmentSatisfaction   1100 non-null   int64\n",
      " 5   JobLevel                  1100 non-null   int64\n",
      " 6   JobSatisfaction           1100 non-null   int64\n",
      " 7   MaritalStatus             1100 non-null   int64\n",
      " 8   MonthlyIncome             1100 non-null   int64\n",
      " 9   NumCompaniesWorked        1100 non-null   int64\n",
      " 10  PercentSalaryHike         1100 non-null   int64\n",
      " 11  PerformanceRating         1100 non-null   int64\n",
      " 12  RelationshipSatisfaction  1100 non-null   int64\n",
      " 13  StockOptionLevel          1100 non-null   int64\n",
      " 14  TotalWorkingYears         1100 non-null   int64\n",
      " 15  WorkLifeBalance           1100 non-null   int64\n",
      " 16  YearsAtCompany            1100 non-null   int64\n",
      " 17  YearsInCurrentRole        1100 non-null   int64\n",
      " 18  YearsSinceLastPromotion   1100 non-null   int64\n",
      " 19  YearsWithCurrManager      1100 non-null   int64\n",
      " 20  Attrition                 1100 non-null   int64\n",
      " 21  Gender_Female             1100 non-null   bool \n",
      " 22  Gender_Male               1100 non-null   bool \n",
      " 23  OverTime_No               1100 non-null   bool \n",
      " 24  OverTime_Yes              1100 non-null   bool \n",
      "dtypes: bool(4), int64(21)\n",
      "memory usage: 184.9 KB\n",
      "None\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_14952\\3148039736.py:1: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df['MaritalStatus'] = df['MaritalStatus'].apply(lambda  x: 0 if x in ['Divorced','Single'] else 1)\n",
      "C:\\Users\\Administrator\\AppData\\Local\\Temp\\ipykernel_14952\\3148039736.py:2: SettingWithCopyWarning: \n",
      "A value is trying to be set on a copy of a slice from a DataFrame.\n",
      "Try using .loc[row_indexer,col_indexer] = value instead\n",
      "\n",
      "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n",
      "  df['Department'] = df['Department'].apply(lambda  x:0 if x in ['Sales','Human Resources'] else 1)\n"
     ]
    }
   ],
   "source": [
    "df['MaritalStatus'] = df['MaritalStatus'].apply(lambda  x: 0 if x in ['Divorced','Single'] else 1)\n",
    "df['Department'] = df['Department'].apply(lambda  x:0 if x in ['Sales','Human Resources'] else 1)\n",
    "# df['MaritalStatus'] = df['MaritalStatus'].map({\n",
    "#             'Divorced': 0,\n",
    "#             'Single': 0,\n",
    "#             'Married': 1\n",
    "#         }).fillna(-1).astype(int)\n",
    "# df['Department'] = df['Department'].map({\n",
    "#             'Sales': 0,\n",
    "#             'Human Resources': 0,\n",
    "#             'Research & Development': 1\n",
    "#         }).fillna(-1).astype(int)\n",
    "# print(df.info())\n",
    "\n",
    "df2 = pd.get_dummies(df)\n",
    "print(df2.info())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:01:29.096919300Z",
     "start_time": "2025-06-07T03:01:29.076767700Z"
    }
   },
   "id": "69e52a7a5fcad1b4"
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 1100 entries, 0 to 1099\n",
      "Data columns (total 23 columns):\n",
      " #   Column                    Non-Null Count  Dtype\n",
      "---  ------                    --------------  -----\n",
      " 0   Age                       1100 non-null   int64\n",
      " 1   Department                1100 non-null   int64\n",
      " 2   DistanceFromHome          1100 non-null   int64\n",
      " 3   Education                 1100 non-null   int64\n",
      " 4   EnvironmentSatisfaction   1100 non-null   int64\n",
      " 5   JobLevel                  1100 non-null   int64\n",
      " 6   JobSatisfaction           1100 non-null   int64\n",
      " 7   MaritalStatus             1100 non-null   int64\n",
      " 8   MonthlyIncome             1100 non-null   int64\n",
      " 9   NumCompaniesWorked        1100 non-null   int64\n",
      " 10  PercentSalaryHike         1100 non-null   int64\n",
      " 11  PerformanceRating         1100 non-null   int64\n",
      " 12  RelationshipSatisfaction  1100 non-null   int64\n",
      " 13  StockOptionLevel          1100 non-null   int64\n",
      " 14  TotalWorkingYears         1100 non-null   int64\n",
      " 15  WorkLifeBalance           1100 non-null   int64\n",
      " 16  YearsAtCompany            1100 non-null   int64\n",
      " 17  YearsInCurrentRole        1100 non-null   int64\n",
      " 18  YearsSinceLastPromotion   1100 non-null   int64\n",
      " 19  YearsWithCurrManager      1100 non-null   int64\n",
      " 20  Attrition                 1100 non-null   int64\n",
      " 21  Gender_Female             1100 non-null   bool \n",
      " 22  OverTime_Yes              1100 non-null   bool \n",
      "dtypes: bool(2), int64(21)\n",
      "memory usage: 182.7 KB\n",
      "None\n"
     ]
    }
   ],
   "source": [
    "#去掉重复的object对象\n",
    "df3 = df2.drop(['Gender_Male', 'OverTime_No'], axis=1)\n",
    "print(df3.info())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:01:34.109571100Z",
     "start_time": "2025-06-07T03:01:34.099997900Z"
    }
   },
   "id": "6f6c31043400b5b0"
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "outputs": [],
   "source": [
    "#从预处理后的数据列中找出特征列和标签\n",
    "x = df3[['Age','EnvironmentSatisfaction','JobSatisfaction','MaritalStatus','MonthlyIncome','NumCompaniesWorked','PercentSalaryHike','PerformanceRating','RelationshipSatisfaction','StockOptionLevel','TotalWorkingYears','WorkLifeBalance','YearsAtCompany','YearsInCurrentRole','YearsSinceLastPromotion','Gender_Female','OverTime_Yes']]\n",
    "# x = df3[['Age','EnvironmentSatisfaction','JobSatisfaction','MaritalStatus','MonthlyIncome','NumCompaniesWorked','PercentSalaryHike','PerformanceRating','RelationshipSatisfaction','StockOptionLevel','TotalWorkingYears','WorkLifeBalance','YearsAtCompany','YearsInCurrentRole','YearsSinceLastPromotion','Gender_Female','OverTime_Yes']]\n",
    "# x = df3[['Age','Department','DistanceFromHome','Education','EnvironmentSatisfaction','JobLevel','JobSatisfaction','MaritalStatus','MonthlyIncome','NumCompaniesWorked','PercentSalaryHike','PerformanceRating','RelationshipSatisfaction','StockOptionLevel','TotalWorkingYears','WorkLifeBalance','YearsAtCompany','YearsInCurrentRole','YearsSinceLastPromotion','YearsWithCurrManager','Gender_Female','OverTime_Yes']]\n",
    "y= df3['Attrition']\n",
    "# print(y.info())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:02:02.819150800Z",
     "start_time": "2025-06-07T03:02:02.808702900Z"
    }
   },
   "id": "6a226e42f507b766"
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "outputs": [],
   "source": [
    "le = LabelEncoder()\n",
    "y = le.fit_transform(y)\n",
    "#切分训练集的数据为训练特征集和测试特征集，测试特征集和测试标签集\n",
    "x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=100,stratify=y)\n",
    "#特征的标准化处理\n",
    "transfer = StandardScaler()\n",
    "x_train = transfer.fit_transform(x_train,y_train)\n",
    "x_test = transfer.transform(x_test)\n",
    "\n",
    "\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:02:12.945414900Z",
     "start_time": "2025-06-07T03:02:12.932796100Z"
    }
   },
   "id": "c3c2011f77c40124"
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUC值：0.8064613526570049\n"
     ]
    }
   ],
   "source": [
    "# 创建逻辑回归模型的对象\n",
    "es = LogisticRegression()\n",
    "es.fit(x_train,y_train)\n",
    "# 模型预测\n",
    "y_pred = es.predict_proba(x_test)[:,1]\n",
    "# y_pred = es.predict(x_test)\n",
    "# print(f\"准确率：{accuracy_score(y_test,y_pred)}\")\n",
    "print(f\"AUC值：{roc_auc_score(y_test,y_pred)}\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:02:21.277437100Z",
     "start_time": "2025-06-07T03:02:21.268909900Z"
    }
   },
   "id": "1378dac46488ab3a"
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fitting 3 folds for each of 270 candidates, totalling 810 fits\n",
      "AUC值：0.759057971014493\n",
      "最好的参数组合：{'criterion': 'gini', 'max_depth': 3, 'max_leaf_nodes': None, 'min_samples_leaf': 3, 'min_samples_split': 2}\n"
     ]
    }
   ],
   "source": [
    "#使用决策树模型\n",
    "dfc = DecisionTreeClassifier(max_depth=8,random_state=45)\n",
    "# dfc.fit(x_train,y_train)\n",
    "# #模型预测\n",
    "# y_pred = dfc.predict_proba(x_test)[:,1]\n",
    "# # y_pred = dfc.predict(x_test)\n",
    "# # print(f\"准确率：{accuracy_score(y_test,y_pred)}\")\n",
    "# print(f\"AUC值：{roc_auc_score(y_test,y_pred)}\")\n",
    "# 3 交叉验证时,采用分层抽取\n",
    "param_grid = {\n",
    "    'criterion': ['gini', 'entropy'],\n",
    "    'max_depth': [8, 3, 5, 7, 10],\n",
    "    'min_samples_split': [2, 4, 6],\n",
    "    'min_samples_leaf': [1, 2, 3],\n",
    "    'max_leaf_nodes': [None, 5, 10]\n",
    "}\n",
    "spliter = StratifiedKFold(n_splits=3, shuffle=True,random_state=42)\n",
    "grid_search = GridSearchCV(\n",
    "    estimator=dfc,\n",
    "    param_grid=param_grid,\n",
    "    scoring='roc_auc',\n",
    "    # scoring='accuracy',\n",
    "    cv=spliter,\n",
    "    n_jobs=-1,\n",
    "    verbose=1\n",
    ")\n",
    "grid_search.fit(x_train,y_train)\n",
    "#模型预测\n",
    "y_pred = grid_search.predict_proba(x_test)[:,1]\n",
    "# y_pred = grid_search.predict(x_test)\n",
    "# print(f\"准确率：{accuracy_score(y_test,y_pred)}\")\n",
    "print(f\"AUC值：{roc_auc_score(y_test,y_pred)}\")\n",
    "print(f\"最好的参数组合：{grid_search.best_params_}\")\n",
    "\n",
    "\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:03:57.081191300Z",
     "start_time": "2025-06-07T03:03:54.277507800Z"
    }
   },
   "id": "a00cfdc5b9f5bb8a"
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "AUC值：0.8008756038647343\n",
      "最好的参数组合：{'eta': np.float64(0.4), 'max_depth': np.int64(3), 'n_estimators': np.int64(50)}\n"
     ]
    }
   ],
   "source": [
    "\n",
    "#使用xgboost模型\n",
    "xgbModel = xgb.XGBClassifier(n_estimators=50, objective='multi:softmax',eval_metric='merror', eta=0.1, random_state=45,num_class=len(le.classes_))\n",
    "# xgbModel = xgb.XGBClassifier(n_estimators=50, objective='multi:softmax',eval_metric='merror', eta=0.1, random_state=45,num_class=len(le.classes_))\n",
    "# xgbModel.fit(x_train,y_train)\n",
    "# #模型预测\n",
    "# y_pred = xgbModel.predict(x_test)\n",
    "# print(f\"准确率：{accuracy_score(y_test,y_pred)}\")\n",
    "# print(f\"AUC值：{roc_auc_score(y_test,y_pred)}\")\n",
    "\n",
    "# 3 交叉验证时,采用分层抽取\n",
    "spliter = StratifiedKFold(n_splits=5, shuffle=True,random_state=45)\n",
    "#定义超参数    \n",
    "param_grid = {'max_depth': np.arange(3, 5, 1),'n_estimators': np.arange(50, 100,150),'eta': np.arange(0.4, 1, 0.3) }\n",
    "model = GridSearchCV(estimator=xgbModel,param_grid=param_grid,cv=spliter)\n",
    "model.fit(x_train,y_train)\n",
    "#模型评估\n",
    "y_pred = model.predict_proba(x_test)[:,1]\n",
    "# y_pred = model.predict(x_test)\n",
    "# print(f\"准确率：{accuracy_score(y_test,y_pred)}\")\n",
    "print(f\"AUC值：{roc_auc_score(y_test,y_pred)}\")\n",
    "print(f\"最好的参数组合：{model.best_params_}\")\n"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-07T03:06:11.146949200Z",
     "start_time": "2025-06-07T03:06:10.396720500Z"
    }
   },
   "id": "f4e8df362bf9fd6d"
  },
  {
   "cell_type": "code",
   "execution_count": 197,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-06-06T02:03:37.208834400Z",
     "start_time": "2025-06-06T02:03:37.202317300Z"
    }
   },
   "id": "31f597c828315db3"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [],
   "metadata": {
    "collapsed": false
   },
   "id": "53e852bb357c4b53"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
